package com.oj.controller;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.oj.config.OAuthConfig;
import com.oj.entity.*;
import com.oj.mapper.OAuthMapper;
import com.oj.service.UserService;
import com.oj.util.DateUtil;
import com.oj.util.GoogleOAuth;
import com.oj.util.GiteeOAuth;
import com.oj.util.GithubOAuth;
import com.oj.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.oj.util.CodeMsg.*;

@Slf4j
@Controller
@RequestMapping
public class OAuthController {
    @Autowired
    private OAuthMapper oauthMapper;

    @Autowired
    private UserService userService;
    public OAuth openAuthGoogle(String code) throws Exception {
        GoogleOAuth google = new GoogleOAuth();
        String client_id = OAuthConfig.getGoogleClientID();
        String client_sec = OAuthConfig.getGoogleClientSecret();
        OAuth user = google.login(client_id, client_sec, code);
        return user;
    }
    public OAuth openAuthGitee(String code) throws Exception {
        GiteeOAuth gitee = new GiteeOAuth();
        String client_id = OAuthConfig.getGiteeClientID();
        String client_sec = OAuthConfig.getGiteeClientSecret();
        OAuth user = gitee.login(client_id, client_sec, code);
        return user;
    }

    public OAuth openAuthGithub(String code) throws Exception {
        GithubOAuth github = new GithubOAuth();
        String client_id = OAuthConfig.getGithubClientID();
        String client_sec = OAuthConfig.getGithubClientSecret();
        OAuth user = github.login(client_id, client_sec, code);
        return user;
    }

    @GetMapping(value = {"/auth/{provider}"})
    public String oauth(@PathVariable String provider, @RequestParam(name = "code") String code,
                        HttpServletRequest request, HttpServletResponse response) {
        try {
            log.info(provider + code);
            OAuth oauth = new OAuth();
            if (provider.equals("github")) {
                oauth = openAuthGithub(code);
            } else if (provider.equals("gitee")) {
                oauth = openAuthGitee(code);
            } else if (provider.equals("google")) {
                oauth = openAuthGoogle(code);
            } else {
                return null;
            }
            if (oauth == null) {
                return null;
            }

            User user_ = new User();
            OAuth oauth_ = oauthMapper.queryOAuthByLoginName(oauth.getProvider(), oauth.getLogin());
            if (oauth_ == null) {
                log.info(oauth.getProvider() + " " + oauth.getLogin() + " binding.");
                user_ = userService.getUserBySession(request);
                if (user_ == null) {
                    return "redirect:/registration";
                }
                oauth_ = new OAuth();
                oauth_.setUsername(user_.getUsername());
                oauth_.setLogin(oauth.getLogin());
                oauth_.setProvider(oauth.getProvider());
                oauth_.setAvatar_url(oauth.getAvatar_url());
                oauth_.setNickname(oauth.getNickname());
                Date dt = new Date();
                SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                oauth_.setCreate_date(Timestamp.valueOf(simpleDate.format(dt)));
                oauthMapper.save(oauth_);
            } else {
                log.info(oauth_.getProvider() + " " + oauth_.getLogin() + " " + oauth_.getUsername() + " login.");
                oauth_.setAvatar_url(oauth.getAvatar_url());
                user_ = userService.query(oauth_.getUsername());
                if (user_ == null) {
                    return null;
                }
            }

            if(!userService.login(request, response, user_.getUsername(), user_.getPassword())){
                return null;
            }

            String avatar_url = user_.getAvatar();
            if (avatar_url == null || "N".equals(avatar_url) || "".equals(avatar_url)) {
                avatar_url = oauth_.getAvatar_url();
            } else {
                if ("Y".equals(avatar_url)) {
                    avatar_url = "/upload/userphoto/" + user_.getUsername() + "/photo.png";
                }
            }
            user_.setAvatar(avatar_url);
            userService.update(user_);
            request.getSession().setAttribute("session_user_avatar_url", avatar_url);

            try {
                String url = request.getSession().getAttribute("session_url").toString();
                if (url != null) {
                    return "redirect:" + url;
                }
                return "redirect:/";
            } catch (Exception e) {
                return "redirect:/";
            }
        } catch (Exception e) {
            log.error(e.toString());
            return null;
        }
    }

    @GetMapping(value = {"/unauth/{provider}"})
    public String oauth(@PathVariable String provider, HttpServletRequest request) {
        User user = userService.getUserBySession(request);
        if (user == null) {
            return null;
        }

        OAuth oauth = oauthMapper.queryOAuthByUser(provider, user.getUsername());
        if (oauth != null) {
            oauthMapper.delete(oauth.getId());
        }
        return "redirect:/settings";
    }
}